/**
 * jGrid plugin depend on jQuery.js and DWZ.js
 *
 * @param {type} $ jQuery
 * @param {type} win window
 * @returns {undefined}
 */
var DWZ = DWZ || {}, alertMsg = alertMsg || {}, navTab = navTab || {};
(function ($, win, DWZ, alertMsg, navTab) {
    var queryButtonText = queryButtonText || '查询', advancedQueryText = advancedQueryText || '高级查询',
        pagePanelShow = pagePanelShow || '显示', pagePanelTotal = pagePanelTotal || '共',
        pagePanelTotalItems = pagePanelTotalItems || '条', queryColon = queryColon || '：',
        noRightDescription = noRightDescription || '没有权限操作', checkParameters = function (args) {
            if (args.length === 0 || (!$.isPlainObject(args[0]) && typeof args[0] !== "string")) {
                console.error("Invalid parameter.");
                return false;
            }
            return true;
        },
        // 列属性转换为条件查询属性
        columnToQuery = function (column) {
            var query = {};
            $.each(column, function (key, value) {
                if (key === 'queryField') {
                    query.field = value;
                } else if (key === 'queryType') {
                    query.type = value;
                } else if (key === 'queryOptions') {
                    query.options = value;
                } else if (key === 'queryRender') {
                    query.render = value;
                } else {
                    if (key === 'field' && column.queryField) {
                        return true;
                    }
                    query[key] = value;
                }
            });
            return query;
        },
        // 工具
        _$ = {
            // 节流器，间隔时间内连续相同的操作仅执行最后一次
            throttle: function () {
                var isClear = arguments[0], fn;
                if (typeof isClear === 'boolean') {
                    fn = arguments[1];
                    fn.__throttleId && clearTimeout(fn.__throttleId);
                } else {
                    fn = isClear;
                    var param = arguments[1], p = $.extend({
                        context: null,
                        args: [],
                        time: 300
                    }, param);
                    arguments.callee(true, fn);
                    fn.__throttleId = setTimeout(function () {
                        fn.apply(p.context, p.args);
                    }, p.time);
                }
            },
            // 缓行器，连续相同的操作每间隔一段时间执行一次
            amble: function () {
                var fn = arguments[0], param = arguments[1], p = $.extend({
                    context: null,
                    args: [],
                    time: 300
                }, param), time = new Date().getTime(), throttleId = fn.__throttleId;
                if (!fn.__prevtime) {
                    fn.apply(p.context, p.args);
                    fn.__prevtime = time;
                } else {
                    if (time > fn.__prevtime + p.time) {
                        fn.apply(p.context, p.args);
                        fn.__prevtime = time;
                    }
                    // 最后一次执行
                    //_$.throttle(fn, param);
                }
            },
            // 获取事件触发位置
            getEventPosition: function (dom, e) {
                var rect = dom && dom.getBoundingClientRect(), event = e || window.event;
                return event && dom && {
                    left: event.clientX - rect.left,
                    top: event.clientY - rect.top,
                    width: rect.width,
                    height: rect.height
                };
            }
        };

    $.fn.extend({
        // 获取输入框的标准日期（非字符串）
        getDate: function () {
            var value = $(this).val().trim(), format = arguments[0] || 'yyyy-MM-dd';
            if (!value) {
                return '';
            }
            try {
                return value.parseDate(format);
            } catch (e) {
                console.error(e);
            }
            return value;
        },
        // 树表组件，基于jGrid组件，配置默认属性
        jTreeGrid: function () {
            if (!checkParameters(arguments)) {
                return;
            }
            if ($.isPlainObject(arguments[0])) {
                var ops = $.extend(true, arguments[0], {
                    orderable: false,
                    pageable: false,
                    treeTable: true,
                    treeModel: 'collapsed' // 'expanded' || 'collapsed'
                });
                return this.jGrid(ops);
            } else {
                return this.jGrid(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
            }
        },
        // jGrid组件
        jGrid: function () {
            if (!checkParameters(arguments)) {
                return;
            }
            if ($.isPlainObject(arguments[0])) {
                // 列表生成
                var ops = arguments[0];
                return this.each(function () {
                    var grid = {}, $this = $(this), $form;
                    // 默认属性
                    grid.options = {
                        // 表宽
                        width: 0,
                        // layoutH布局
                        layoutH: 0,
                        // 表头高度
                        gridHeaderHeight: 27,
                        // url根路径
                        base: '',
                        // ajax数据源
                        url: '',
                        // 初始查询条件
                        data: {},
                        // 立即自动加载数据
                        autoLoad: true,
                        // td内包裹div
                        wrapTD: true,
                        // 表格边框
                        hasBorder: false,
                        // 行可选中
                        trselectable: true,
                        // 表格列
                        columns: [],
                        // 表格列宽度可变
                        columnresizeable: true,
                        // Shift + 鼠标左键 可选中多行的checkbox
                        _shiftbox: '',
                        // 列固定
                        lockColumnNum: 0,
                        // 排序
                        orderable: true,
                        // 单列排序或多列排序 'multiple' || 'single'
                        ordertype: 'single',
                        // 分页查询
                        pageable: true,
                        page: {
                            pageNum: 1,
                            numPerPage: 20,
                            pageNumShown: 5,
                            numPerPages: [10, 20, 30, 50, 100, 200]
                        },
                        pagination: {},
                        // 条件查询
                        queryable: false,
                        query: {
                            button: queryButtonText,
                            numPerRow: 3,
                            queryfields: [],
                            advancedqueryfields: []
                        },
                        // 列表按钮
                        gridbars: [],
                        // 填充的数据， autoLoad为false时会生效，否则会调用ajax获取的数据
                        fillData: [],
                        // 数据填充完的回调
                        fillcallback: $.noop,
                        // 内部表
                        inner: false,
                        // 行可拖拽排序
                        rowsortable: false
                    };
                    $.extend(true, grid.options, ops);
                    // 内部表时默认设置相应属性
                    if (grid.options.inner) {
                        grid.options.columnresizeable = false;
                        grid.options.orderable = false;
                        grid.options.pageable = false;
                        grid.options.queryable = false;
                    }
                    // 没有使用layoutH布局且设置高度为100%时
                    if (grid.options.layoutH === 0 && (grid.options.height === 0 || grid.options.height === '100%')) {
                        grid.options.height = $this.height() - 30;
                    }
                    // 生成随机字符串
                    var getRandomStr = function () {
                            return Math.random().toString(36).substring(2);
                        },
                        // 转换条件，选中单行时的操作，例如编辑、详情
                        transformData = function (bar, postData) {
                            var data = bar.data || {}, needSelectedTr = false, needSelectedCheckbox = false;
                            $.extend(postData, {
                                _grid: grid._gridId
                            });
                            $.each(data, function (key, value) {
                                if (/^\{.*\}$/.test(value)) {
                                    if (grid.options.checkGroup === value.slice(1, -1)) {
                                        bar.select = bar.select || key;
                                        needSelectedCheckbox = true;
                                    } else {
                                        needSelectedTr = true;
                                    }
                                    return false;
                                }
                            });
                            if (bar.select && bar.select === grid.options.checkGroup) {
                                needSelectedCheckbox = true;
                            }
                            if (needSelectedTr) {
                                if (grid.tbody.find('tr.selected').length === 0) {
                                    alertMsg.error(bar.warn || DWZ.msg("alertSelectMsg"));
                                    return false;
                                }
                                var trData = grid.tbody.find('tr.selected:first').data();
                                $.each(data, function (key, value) {
                                    if (/^\{.*\}$/.test(value)) {
                                        if (trData[value.slice(1, -1)] !== null) {
                                            postData[key] = trData[value.slice(1, -1)];
                                        } else {
                                            postData[key] = '';
                                        }
                                    } else if (/^\$\(.*\)$/.test(value)) {
                                        try {
                                            postData[key] = eval(value.slice(2, -1));
                                        } catch (e) {
                                            console.error("Global variable is not existing. " + e);
                                        }
                                    } else if ($.isFunction(value)) {
                                        postData[key] = value(trData);
                                    } else {
                                        postData[key] = value;
                                    }
                                });
                            } else if (needSelectedCheckbox) {
                                return transformSelectData(bar, postData);
                            } else {
                                $.extend(true, postData, data);
                            }
                            return true;
                        },
                        // 选中多行的checkbox的选中值
                        transformSelectData = function (bar, data) {
                            $.extend(true, data, bar.data || {});
                            var ids = '';
                            $.each(grid.tbody.find('input[type="checkbox"][name="' + grid.options.checkGroup + '"]'), function () {
                                if (this.checked) {
                                    ids += (this.value + ',');
                                }
                            });
                            if (!ids) {
                                alertMsg.error(DWZ.msg("alertSelectMsg"));
                                return false;
                            } else {
                                ids = ids.slice(0, -1);
                            }
                            data[bar.select] = ids;
                            $.each(data, function (key, value) {
                                if (/^\$\(.*\)$/.test(value)) {
                                    try {
                                        data[key] = eval(value.slice(2, -1));
                                    } catch (e) {
                                        console.error("Global variable is not existing. " + e);
                                    }
                                }
                            });
                            return true;
                        },
                        // 生成列表按钮
                        createGridBar = function () {
                            var $gridBar = $('<div/>').addClass('panelBar headBar'),
                                $bars = $('<ul/>').addClass('toolBar'),
                                // 按钮默认支持dialog（一般用于新增、编辑、详情等）、selectedTodo（一般用于删除操作）、navTab（标签页）、ajaxTodo（ajax请求）、confirmTodo（确认？）、action（自定义处理）、export（列表导出功能）
                                // 各个功能现在系统中均有实现，后端请参照相应的代码自行实现，前端只是进行了高度封装，尽量减少前后端的编码
                                targets = ['dialog', 'selectedTodo', 'navTab', 'ajaxTodo', 'confirmTodo', 'action', 'export'];
                            $.each(grid.options.gridbars, function (barIndex, bar) {
                                var $bar;
                                //HAS_ALL_ACCESSDECISION新增超级管理员
                                if (bar.menuCode && window.buttonAuthorities && !window.buttonAuthorities[bar.menuCode.toUpperCase()]
                                    && !window.buttonAuthorities['HAS_ALL_ACCESSDECISION']) {
                                    var noRight = "<li><a class='noright' title='" + noRightDescription + "'><span style='color:#D8D1D1;'>" + bar.text + "</span></a></li>";
                                    $bar = $(noRight).appendTo($bars);
                                    $bar.on('click', 'a.noright', function (event) {
                                        var title = $(this).attr("title");
                                        alertMsg.error(title);
                                        event.preventDefault();
                                    });
                                    return true;
                                }
                                if (bar.type === 'button') {
                                    $bar = $('<div class="buttonActive"/>').append($('<div class="buttonContent"/>').append($('<button/>').text(bar.text)));
                                } else {
                                    $bar = $('<a/>').addClass(bar.icon || '').attr({
                                        title: bar.title,
                                        rel: bar.rel,
                                        href: (targets.indexOf && targets.indexOf(bar.target) !== -1 || checkIndexOf(targets, bar.target) !== -1) ? 'javascript:void(0);' : grid.options.base + bar.href,
                                        target: (targets.indexOf && targets.indexOf(bar.target) !== -1 || checkIndexOf(targets, bar.target) !== -1) ? '' : bar.target,
                                        targetType: bar.targetType
                                    }).append($('<span/>').append(bar.text));
                                }
                                $bar.on('click', function (event) {
                                    $('#calendar', $('body')).remove();
                                    if (bar.preCheck && $.isFunction(bar.preCheck) && !bar.preCheck.apply(bar, [$bar])) {
                                        return false;
                                    }
                                    if (!bar.href && !bar.action) {
                                        return false;
                                    }
                                    if (bar.target === 'dialog') {
                                        var url = grid.options.base + bar.href, rel = bar.rel || getRandomStr(),
                                            title = bar.title || bar.text, data = {}, options = {};
                                        DWZ.debug(url);
                                        if (!url.isFinishedTm()) {
                                            return false;
                                        }
                                        if (!transformData(bar, data)) {
                                            return false;
                                        }
                                        options.data = data;
                                        options.max = bar.max || false;
                                        options.mask = bar.mask || true;
                                        options.maxable = bar.maxable || false;
                                        options.minable = bar.minable || false;
                                        options.fresh = bar.fresh || true;
                                        options.resizable = bar.resizable || false;
                                        options.drawable = bar.drawable || true;
                                        options.close = bar.close || '';
                                        options.param = bar.param || '';
                                        options._lookup = bar._lookup;
                                        var $parent = $this.closest('.dialogContent.unitBox');
                                        if ($parent.length === 0) {
                                            $parent = $this.closest('.page.unitBox');
                                        }
                                        options._parent = $parent;
                                        if (bar.width)
                                            options.width = bar.width;
                                        if (bar.height)
                                            options.height = bar.height;
                                        if (bar.preevent) {
                                            if ($.isFunction(bar.preevent) && !bar.preevent()) {
                                                return false;
                                            } else if (typeof bar.preevent === 'string' && !eval(bar.preevent + "()")) {
                                                return false;
                                            }
                                        }
                                        $.pdialog.open(url, rel, title, options);
                                        event.preventDefault();
                                    } else if (bar.target === 'selectedTodo') {
                                        var url = grid.options.base + bar.href, data = {};
                                        DWZ.debug(url);
                                        if (!url.isFinishedTm()) {
                                            return false;
                                        }
                                        if (!transformData(bar, data)) {
                                            return false;
                                        }
                                        var _doPost = function () {
                                            DWZ.ajax({
                                                type: 'POST',
                                                url: url,
                                                dataType: 'json',
                                                cache: false,
                                                data: data,
                                                alert: false,
                                                success: function (json) {
                                                    $.jGridTool.loadData(grid);
                                                    if (json.data) {
                                                        if (!DWZ.showDetailedReports(json) && json[DWZ.keys.message] && alertMsg) {
                                                            alertMsg.correct(json[DWZ.keys.message]);
                                                        }
                                                    } else if (json[DWZ.keys.message] && alertMsg) {
                                                        alertMsg.correct(json[DWZ.keys.message]);
                                                    }
                                                }
                                            });
                                        };
                                        if (bar.title) {
                                            if ($.isFunction(bar.action)) {
                                                alertMsg.confirm(bar.title, {
                                                    okCall: function () {
                                                        bar.action(data);
                                                    }
                                                });
                                            } else {
                                                alertMsg.confirm(bar.title, {
                                                    okCall: _doPost
                                                });
                                            }
                                        } else {
                                            if ($.isFunction(bar.action)) {
                                                bar.action(data);
                                            } else {
                                                _doPost();
                                            }
                                        }
                                        event.preventDefault();
                                    } else if (bar.target === 'navTab') {
                                        var title = bar.title || bar.text, tabid = bar.rel || getRandomStr(),
                                            fresh = bar.fresh || true, external = bar.external || false,
                                            url = grid.options.base + bar.href, data = {};
                                        DWZ.debug(url);
                                        if (!url.isFinishedTm()) {
                                            return false;
                                        }
                                        if (!transformData(bar, data)) {
                                            return false;
                                        }
                                        navTab.openTab(tabid, url, {
                                            data: data,
                                            title: title,
                                            fresh: fresh,
                                            external: external
                                        });
                                        event.preventDefault();
                                    } else if (bar.target === 'ajaxTodo') {
                                        var title = bar.title, url = grid.options.base + bar.href, data = {};
                                        DWZ.debug(url);
                                        if (!url.isFinishedTm()) {
                                            return false;
                                        }
                                        if (!transformData(bar, data)) {
                                            return false;
                                        }
                                        if (title) {
                                            alertMsg.confirm(title, {
                                                okCall: function () {
                                                    ajaxTodo(url, bar.callback, data);
                                                }
                                            });
                                        } else {
                                            ajaxTodo(url, bar.callback, data);
                                        }
                                        event.preventDefault();
                                    } else if (bar.target === 'confirmTodo') {
                                        if (bar.title) {
                                            alertMsg.confirm(bar.title, {
                                                okCall: bar.action
                                            });
                                        } else {
                                            bar.action.apply(bar);
                                        }
                                        event.preventDefault();
                                    } else if (bar.target === 'action' && $.isFunction(bar.action)) {
                                        bar.action.apply(bar);
                                        event.preventDefault();
                                    } else if (bar.target === 'export') {
                                        // 列表导出，有详细的注释
                                        if ($('>tr .noData', grid.tbody).length || $('>tr', grid.tbody).length === 0) {
                                            alertMsg.error('没有可导出的数据！');
                                            return false;
                                        }
                                        var _doExport = function () {
                                            var url = grid.options.base + bar.href,
                                                $exportForm = $('body').data('_exportForm'), cols = {
                                                    _length: 0
                                                },
                                                // 往form里添加input标签，从而支持大数据量的参数
                                                appendFieldInput = function (name, value) {
                                                    $exportForm.append($('<input type="text" name="' + name + '">').val(value));
                                                };
                                            // 创建专门下载使用的form
                                            if (!$exportForm) {
                                                $exportForm = $('<form id="_exportForm" method="POST"/>').hide().appendTo($('body'));
                                                $('body').data('_exportForm', $exportForm);
                                            }
                                            // 清空form，避免上次下载时遗留的无用的参数
                                            $exportForm.empty();
                                            // 组装导出列的表头数据，后台只需要接收colsMap字符串，反序列化为LinkedHashMap即可，
                                            // 不用定义map再往里面put各个表头的字段及描述
                                            $.each(grid.options.columns, function () {
                                                if (this.field === '_index' || this.field === '_lookup') {
                                                    return true;
                                                }
                                                // 可以单独定义后台导出的字段exportField，默认就是表头字段field
                                                var exportField = this.exportField || this.field;
                                                cols[exportField] = this.text;
                                                cols._length = cols._length + 1;
                                            });
                                            // 如果有导出的列
                                            if (cols._length > 0) {
                                                delete cols._length;
                                                var colsMap = JSON.stringify(cols);
                                                appendFieldInput('colsMap', colsMap);
                                            }
                                            // 支持对有分页的列表导出全部，后台使用带分页的接口查询即可，不用再重新定义单独的接口
                                            // 原理是设置页码为1，
                                            // 每页的数量为查出来的数据总量totalCount，请酌情使用，excel最大支持的行数为65535
                                            var _export = {};
                                            if (grid.options.pageable && bar.exportAll) {
                                                _export = {
                                                    pageNum: 1,
                                                    startRow: 1,
                                                    numPerPage: grid.options.pagination.totalCount,
                                                    endRow: grid.options.pagination.totalCount
                                                };
                                            }
                                            // 获取查询列表时的参数，并且加入传入的额外的参数及是否导出全部的参数
                                            var postData = $.extend(true, {}, grid.options.postData, _export, bar.data || {});
                                            // 将参数转换为url的参数格式
                                            var param = $.param(postData);
                                            // 将url设置给form的action属性
                                            $exportForm.attr({
                                                action: url + (url.indexOf('?') === -1 ? "?" : "&") + param
                                            });
                                            // 提交form表单，实现下载
                                            $exportForm.submit();
                                            // 删除form表单的action属性
                                            $exportForm.removeAttr('action');
                                        };
                                        if (bar.title) {
                                            alertMsg.confirm(bar.title, {
                                                okCall: _doExport
                                            });
                                        } else {
                                            _doExport();
                                        }
                                        event.preventDefault();
                                    }
                                });
                                var $li = $('<li class=""/>').append($bar).appendTo($bars);
                                if (bar.id || bar.menuCode) {
                                    $li.attr('id', (bar.id || bar.menuCode));
                                }
                                if ($.isFunction(bar.render)) {
                                    bar.render($li);
                                }
                            });
                            return $gridBar.append($bars);
                        },
                        // 生成表格主体
                        appendGrid = function () {
                            var $grid = $('<div/>').addClass('grid gridPart'),
                                $gridScrollerBar = $('<div/>').addClass('gridScrollerBar').css({
                                    overflowX: 'auto'
                                }).append('<div/>'), $gridHeader = $('<div/>').addClass('gridHeader'),
                                gridWith = grid.options.hasBorder ? $this.width() - 1 : $this.width(),
                                $gridBody = $('<div/>').addClass('gridBody'),
                                $resizeMarker = $('<div/>').addClass('resizeMarker').css({
                                    height: '300px',
                                    left: '57px',
                                    display: 'none'
                                }), $resizeProxy = $('<div>').addClass('resizeProxy').css({
                                    height: '300px',
                                    left: '377px',
                                    display: 'none'
                                }),
                                $thead = $('<thead/>').appendTo($('<table/>').appendTo($('<div/>').addClass('gridThead').appendTo($gridHeader))),
                                $tbody = $('<tbody/>').appendTo($('<table/>').addClass(grid.options.treeTable ? 'treetable' : '').appendTo($('<div/>').addClass('gridTbody').appendTo($gridBody))),
                                getTrIndex = function ($tr) {
                                    var index = 0, $tr = $tr.prev('tr');
                                    while ($tr.length) {
                                        index++;
                                        $tr = $tr.prev('tr');
                                    }
                                    return index;
                                };

                            // 事件委托机制，绑定事件到tbody上，不依赖于已存在的$trs
                            $tbody.on('click', 'tr', function (event) {
                                var e = event || window.event, $tr = $(this), oldIndex = -1, newIndex = -1;
                                if (grid.options._shiftbox && e.shiftKey) {
                                    if ($('>tr.selected', $tbody).length) {
                                        oldIndex = getTrIndex($('>tr.selected:first', $tbody));
                                    }
                                    newIndex = getTrIndex($tr);
                                    if (oldIndex !== -1 && newIndex !== -1 && oldIndex !== newIndex) {
                                        $('>tr :checkbox[name="' + grid.options._shiftbox + '"]', $tbody).attr({
                                            checked: false
                                        });
                                        var start = oldIndex > newIndex ? newIndex : oldIndex,
                                            end = oldIndex < newIndex ? newIndex : oldIndex;
                                        for (var int = start; int <= end; int++) {
                                            $('>tr:eq(' + int + ') :checkbox[name="' + grid.options._shiftbox + '"]', $tbody)[0].checked = true;
                                        }
                                    }
                                }
                                if (grid.options.trselectable) {
                                    $('>tr.selected', $tbody).removeClass('selected');
                                    $tr.addClass('selected');
                                }
                                if ($.isFunction(grid.options.trclick)) {
                                    grid.options.trclick($tr, $tr.data(), grid.options.troptions || {});
                                }
                            });
                            if ($.isFunction(grid.options.trdblclick)) {
                                $tbody.on('dblclick', 'tr', function (event) {
                                    var $tr = $(this);
                                    grid.options.trdblclick($tr, $tr.data(), grid.options.troptions || {});
                                });
                            }

                            $tbody.on('mouseenter', 'tr', function () {
                                $(this).addClass('hover');
                            }).on('mouseleave', 'tr', function () {
                                $(this).removeClass('hover');
                            });

                            grid.options.rowsortable && !function () {
                                var mosudown = false, _rows = null, target, detached = false,
                                    appendRow = function (row) {
                                        if (!isNaN(_rows)) {
                                            if (_rows === 0) {
                                                $tbody.prepend(row);
                                            } else if (_rows === $tbody.find('>tr:not(.sortDragOccupancy)').length) {
                                                $tbody.append(row);
                                            } else {
                                                $tbody.find('>tr:not(.sortDragOccupancy):eq(' + (_rows - 1) + ')').after(row);
                                            }
                                        }
                                        $.jGridTool.refresh(grid);
                                    },
                                    // 拖拽
                                    drag = function ($ele, e) {
                                        var $rows = $tbody.find('>tr:not(.sortDragOccupancy)'), $first = $rows.eq(0),
                                            rowH = $first.height(),
                                            rows = Math.floor((_$.getEventPosition($ele[0], e).top + $ele.scrollTop()) / rowH);
                                        rows = Math.min(rows, $rows.length);
                                        if (rows !== _rows) {
                                            var $temp = $first.clone();
                                            $temp.addClass('sortDragOccupancy').css({
                                                height: '5px',
                                                background: '#CEF8CE'
                                            });
                                            $temp.find('>td').each(function () {
                                                $(this).empty();
                                            });
                                            $tbody.find('.sortDragOccupancy').remove();
                                            _rows = rows;
                                            appendRow($temp);
                                        }
                                    }, drop = function () {
                                        if (target && !isNaN(_rows)) {
                                            if (mosudown) {
                                                $tbody.find('.sortDragOccupancy').remove();
                                            }
                                            appendRow(target);
                                            detached = false;
                                            mosudown = false;
                                            _rows = null;
                                            target = null;
                                            $tbody.css('cursor', '');
                                        }
                                    };

                                $tbody.on('mousedown', 'tr', function (e) {
                                    var tagName = e.target && e.target.tagName && e.target.tagName.toLowerCase();
                                    if ($tbody.find('>tr:not(.sortDragOccupancy)').length <= 1 || tagName == 'input' || tagName == 'select' || tagName == 'button') {
                                        return;
                                    }
                                    mosudown = true;
                                    $tbody.css('cursor', 'move');
                                    target = $(this);
                                });
                                $gridBody.on('mouseleave', drop).on('mousemove', function (e) {
                                    if (mosudown && target) {
                                        if (target && !detached) {
                                            target.detach();
                                            $.jGridTool.refresh(grid);
                                        }
                                        //drag(e);
                                        _$.amble(drag, {
                                            args: [$gridBody, e]
                                        });
                                    }
                                });
                                $(document).on('mouseup', drop);
                            }();

                            grid.thead = $thead;
                            grid.tbody = $tbody;
                            grid.orders = {};
                            grid.defaultOrderString = grid.options.defaultOrderString || '';
                            grid._gridId = getRandomStr();
                            $this.attr('grid-id', grid._gridId);
                            $gridScrollerBar.scroll(function (event) {
                                var scroll = $gridScrollerBar.scrollLeft();
                                $(".gridThead, .gridTbody", $grid).css({
                                    position: 'relative',
                                    left: 0 - scroll
                                });
                                if (grid.options.lockColumnNum > 0) {
                                    $.jGridTool.lockColumn(grid);
                                }
                                return false;
                            });
                            $grid.append($gridHeader).append($gridBody).append($gridScrollerBar).append($resizeMarker).append($resizeProxy).appendTo($this);
                            $.jGridTool.fillGridHeader(grid);
                        },
                        // 生成分页
                        createPageBar = function () {
                            var $pagePanel = $('<div class="panelBar footBar"/>'), $pages = $('<div class="pages"/>'),
                                $pagination = $('<span class="pagination"/>'),
                                $select = $('<select class="combox" />').attr('name', 'numPerPage');

                            $.each(grid.options.page.numPerPages, function () {
                                var $op = $('<option/>').text(this).attr({
                                    value: this
                                }).appendTo($select);
                                if (this == grid.options.page.numPerPage) {
                                    $op.attr({
                                        selected: 'selected'
                                    });
                                }
                            });

                            $pages.append('<span>' + pagePanelShow + '</span>').append($select).append('<span>' + pagePanelTotal + '</span>').append('<span name="totalCount">0' + pagePanelTotalItems + '</span>');

                            grid.pagination = $pagination;
                            createPagination();
                            $select.combox();
                            $('#op_' + $select.parent().attr('id') + '>li>a').on('click', function () {
                                setPerPage(parseInt($(this).attr('value')));
                            });
                            $pagePanel.append($pages).append($pagination);
                            grid.pagePanel = $pagePanel;
                            grid.page = {
                                numPerPage: grid.options.page.numPerPage,
                                pageNum: grid.options.page.pageNum,
                                startRow: (grid.options.page.pageNum - 1) * grid.options.page.numPerPage + 1,
                                endRow: grid.options.page.pageNum * grid.options.page.numPerPage
                            };
                            return $pagePanel;
                        },
                        // 分页导航
                        createPagination = function () {
                            var $pagination = grid.pagination;

                            grid.firstPage = $('<li class="j-first disabled"/>').append($('<a class="first"/>').append($('<span>').append('首页')).hide().on('click', function () {
                                setPageNum(1);
                            })).append($('<span class="first"/>').append($('<span>').append('首页')));
                            grid.prevPage = $('<li class="j-prev disabled"/>').append($('<a class="previous"/>').append($('<span>').append('上一页')).hide().on('click', function () {
                                setPageNum(grid.page.pageNum - 1);
                            })).append($('<span class="previous"/>').append($('<span>').append('上一页')));
                            grid.nextPage = $('<li class="j-next disabled"/>').append($('<a class="next"/>').append($('<span>').append('下一页')).hide().on('click', function () {
                                setPageNum(grid.page.pageNum + 1);
                            })).append($('<span class="next"/>').append($('<span>').append('下一页')));
                            grid.lastPage = $('<li class="j-last disabled"/>').append($('<a class="last"/>').append($('<span>').append('末页')).hide().on('click', function () {
                                setPageNum(parseInt(grid.pagination.data('totalPageNum')));
                            })).append($('<span class="last"/>').append($('<span>').append('末页')));
                            grid.jumpto = $('<li class="jumpto disabled"/>').append($('<input type="text" style="line-height: 15px;" class="textInput integer"/>').on('keyup', function (event) {
                                var e = event || window.event;
                                if (e.keyCode === 13) {
                                    $(this).next('input').click();
                                }
                            })).append($('<input type="button" class="goto"/>').on('click', function () {
                                var toNum = 1;
                                try {
                                    toNum = parseInt($(this).prev('input').val());
                                    if (toNum < 0 || toNum === 0)
                                        return false;
                                } catch (e) {
                                    return false;
                                }
                                if (toNum < parseInt(grid.pagination.data('totalPageNum')) || toNum === parseInt(grid.pagination.data('totalPageNum'))) {
                                    setPageNum(toNum);
                                }
                            }));
                            $('<ul/>').append(grid.firstPage).append(grid.prevPage).append(grid.nextPage).append(grid.lastPage).append(grid.jumpto).appendTo($pagination);
                        },
                        // 分页跳转
                        setPageNum = function (num) {
                            grid.page.pageNum = num;
                            grid.page.startRow = (num - 1) * grid.page.numPerPage + 1;
                            grid.page.endRow = num * grid.page.numPerPage;
                            $.jGridTool.loadData(grid);
                        }, setPerPage = function (numPerPage) {
                            grid.page.numPerPage = numPerPage;
                            grid.page.pageNum = 1;
                            grid.page.startRow = 1;
                            grid.page.endRow = numPerPage;
                            $.jGridTool.loadData(grid);
                        },
                        // 查询条件
                        appendQueryFields = function (queryfields, $queryBar) {
                            var $searchContent = $('<ul/>').addClass('searchContent');
                            var searchContent = '';
                            $.each(queryfields, function (index, query) {
                                if (query.columnIndex !== undefined) {
                                    $.extend(query, columnToQuery(grid.options.columns[query.columnIndex]));
                                }
                                if (index % grid.options.query.numPerRow === 0) {
                                    if (searchContent) {
                                        searchContent.appendTo($queryBar);
                                    }
                                    searchContent = $searchContent.clone();
                                }
                                if (!query.field) {
                                    searchContent.append('<li/>');
                                    return true;
                                }
                                var $li = $('<li/>').append($('<label/>').text(query.text + queryColon)), $input;

                                var attrObj = {};
                                if (query.id)
                                    attrObj.id = query.id;
                                if (query.field)
                                    attrObj.name = query.field;

                                if (!query.type || query.type === 'text') {
                                    $input = $('<input type="text" autocomplete="off"/>').addClass('textInput').attr(attrObj).addClass(query.required ? 'required' : '').val(query.value || '');
                                    $li.append($input);
                                } else if (query.type === 'date') {
                                    if (query.minDate)
                                        attrObj.minDate = query.minDate;
                                    if (query.maxDate)
                                        attrObj.maxDate = query.maxDate;
                                    if (query.min_date)
                                        attrObj.min_date = query.min_date;
                                    if (query.max_date)
                                        attrObj.max_date = query.max_date;
                                    if (query.dateGroup)
                                        attrObj.dateGroup = query.dateGroup;
                                    attrObj.readonly = 'readonly';
                                    attrObj.dateFmt = query.dateFmt || 'yyyy-MM-dd';
                                    $input = $('<input type="text" class="textInput date" />').addClass(query.required ? 'required' : '').attr(attrObj).val(query.value || '');
                                    $li.append($input).append($('<a class="inputDateButton" href="javascript:;" />'));
                                } else if (query.type === 'select') {
                                    $input = $('<select/>').attr(attrObj).addClass(query.required ? 'required' : '');
                                    $.each(query.options, function () {
                                        $('<option/>').attr('value', this[query.value || 'value']).text(this[query.label || 'label']).appendTo($input);
                                    });
                                    $li.append($input).wrapInner($('<div/>').css('float', 'left'));
                                }
                                if ($input) {
                                    $input.addClass(query.css || '').on('change', function () {
                                        if ($.isFunction(query.change)) {
                                            query.change($input, $queryBar);
                                        }
                                    });
                                    if ($.isFunction(query.render)) {
                                        query.render($input);
                                    }
                                }
                                searchContent.append($li);
                            });
                            return searchContent;
                        },
                        // 普通查询
                        createQueryPanel = function () {
                            var $queryPanel = $('<div/>').addClass('pageHeader').attr('grid', grid._gridId),
                                $queryBar = $('<div/>').addClass('searchBar'),
                                searchContent = appendQueryFields(grid.options.query.queryfields, $queryBar);

                            var queryBtn = $('<li/>').addClass('query').append($('<div class="buttonActive"/>').append($('<div class="buttonContent"/>').append($('<button/>').text(grid.options.query.button)))).appendTo(searchContent.appendTo($queryBar.appendTo($queryPanel)));

                            var $btn = queryBtn.find('button').on('click', function () {
                                $('#calendar', $('body')).remove();
                                if ($form && !$form.valid()) {
                                    return false;
                                }
                                if (grid.options.pageable) {
                                    setPageNum(1);
                                } else {
                                    $.jGridTool.loadData(grid);
                                }
                                return false;
                            });
                            $queryPanel.on('keydown', 'input, select', function (event) {
                                var e = event || window.event;
                                if (e.keyCode === 13) {
                                    if (!$('#alertMsgBox').is(':visible')) {
                                        setTimeout(function () {
                                            $btn.click();
                                        }, 0);
                                        return false;
                                    }
                                }
                            });
                            grid.queryPanel = $queryPanel;
                            return grid.queryPanel;
                        },
                        // 高级查询
                        createAdvancedQueryPanel = function () {
                            var speed = 400,
                                $advancedQuery = $('<li/>').addClass('advancedQuery').append($('<a/>').append(advancedQueryText)).append($('<span/>')).appendTo($('.searchContent:last', grid.queryPanel)).on('click', 'a, span', function () {
                                    if (grid.advancedQueryPanel.is(':animated')) {
                                        return false;
                                    }
                                    var $gridPart = $this.find('.gridPart'), $gridBody = $this.find('.gridBody');
                                    if ($advancedQuery.is('.expand')) {
                                        grid.queryPanel.next('.divider').hide();
                                        grid.advancedQueryPanel.slideUp(speed, function () {
                                            $advancedQuery.removeClass('expand');
                                        });
                                        $gridPart.attr('layoutH', grid.options.layoutH - grid.options.gridHeaderHeight).height($gridPart.height() + 6).animate({
                                            height: $gridPart.height() + grid.options.query.advancedHeight - 6
                                        }, speed);
                                        $gridBody.attr('layoutH', grid.options.layoutH).height($gridBody.height() + 6).animate({
                                            height: $gridBody.height() + grid.options.query.advancedHeight - 6
                                        }, speed);
                                    } else {
                                        grid.queryPanel.next('.divider').show();
                                        grid.advancedQueryPanel.slideDown(speed, function () {
                                            $advancedQuery.addClass('expand');
                                        });
                                        $gridPart.attr('layoutH', grid.options.layoutH + grid.options.query.advancedHeight - grid.options.gridHeaderHeight).height($gridPart.height() - 7).animate({
                                            height: $gridPart.height() - grid.options.query.advancedHeight + 7
                                        }, speed);
                                        $gridBody.attr('layoutH', grid.options.layoutH + grid.options.query.advancedHeight).height($gridBody.height() - 7).animate({
                                            height: $gridBody.height() - grid.options.query.advancedHeight + 7
                                        }, speed);
                                    }
                                });
                            $('<div class="divider"/>').css({
                                margin: '0px 10px'
                            }).hide().insertAfter(grid.queryPanel);
                            var $advancedQueryPanel = $('<div/>').addClass('pageHeader advancedQueryPanel').attr('grid', grid._gridId).hide(),
                                $queryBar = $('<div/>').addClass('searchBar'),
                                searchContent = appendQueryFields(grid.options.query.advancedqueryfields, $queryBar);
                            $queryBar.append(searchContent).appendTo($advancedQueryPanel);
                            grid.advancedQueryPanel = $advancedQueryPanel;
                            grid.options.query.advancedHeight = 7 + $('.searchContent', $queryBar).length * 29 + 15;
                            return grid.advancedQueryPanel;
                        };
                    appendGrid();
                    if (grid.options.query.queryfields.length > 0) {
                        grid.options.queryable = true;
                        $form = $('<form/>').addClass('required-validate');
                        createQueryPanel().appendTo($form);
                    }
                    if (grid.options.queryable && grid.options.query.advancedqueryfields.length > 0) {
                        createAdvancedQueryPanel().appendTo($form);
                    }
                    if ($form) {
                        $form.insertBefore($this);
                    }
                    if (grid.options.gridbars.length > 0) {
                        createGridBar().prependTo($this);
                    }
                    if (grid.options.page && grid.options.pageable) {
                        createPageBar().appendTo($this);
                    }
                    if (grid.options.hasBorder) {
                        var borderWidth = '{0}px 1px {1}px 1px';
                        if (grid.options.gridbars.length > 0) {
                            borderWidth = borderWidth.replace('{0}', 0);
                        } else {
                            borderWidth = borderWidth.replace('{0}', 1);
                        }
                        if (grid.options.page && grid.options.pageable) {
                            borderWidth = borderWidth.replace('{1}', 0);
                        } else {
                            borderWidth = borderWidth.replace('{1}', 1);
                        }
                        $this.css({
                            borderWidth: borderWidth,
                            borderStyle: 'solid',
                            borderColor: '#D9DFE5'
                        });
                    }
                    if (grid.options.url && grid.options.autoLoad) {
                        $.jGridTool.loadData(grid);
                    } else {
                        $.jGridTool.fillGrid(grid, grid.options.fillData);
                    }
                    $this.data('_grid', grid);
                });
            } else if (typeof arguments[0] === "string" && arguments[0] !== 'option') {
                // 方法调用
                var gridFun = arguments[0], ops = arguments,
                    gridFuns = ["fillGrid", "loadData", "lockColumn", "insertRow", "appendRow", "clearData", "refresh", "option"];
                return this.each(function () {
                    if (gridFuns.indexOf && gridFuns.indexOf(gridFun) !== -1 || checkIndexOf(gridFuns, gridFun) !== -1) {
                        var $this = $(this), _grid = $this.data('_grid');
                        $.jGridTool[gridFun](_grid, ops[1], ops[2]);
                    } else {
                        console.error('$(...).jGrid("' + gridFun + '") is not a function.');
                        return false;
                    }
                });
            } else if (typeof arguments[0] === "string" && arguments[0] === 'option') {
                if (arguments[1] && $.isPlainObject(arguments[1])) {
                    var ops = arguments[1];
                    return this.each(function () {
                        $.jGridTool.option($(this).data('_grid'), ops);
                    });
                } else {
                    if (this.length && this.length === 1) {
                        var _grid = this.data('_grid');
                        return _grid.options;
                    } else if (this.length && this.length > 1) {
                        var options = new Array();
                        this.each(function () {
                            var _grid = $(this).data('_grid');
                            options.push(_grid.options);
                        });
                        return options;
                    } else {
                        return undefined;
                    }
                }
            }
        }
    });

    $.jGridTool = {
        // ajax加载数据
        loadData: function (grid) {
            var data = arguments[1] || {};
            $.each(grid.thead.find('th:first input[type=checkbox]'), function () {
                this.checked = false;
            });
            if (!grid.options.url) {
                if (data.url) {
                    grid.options.url = data.url;
                    delete data.url;
                } else {
                    console.error("There is no url to get the data.");
                    return;
                }
            }
            var url = grid.options.base + grid.options.url;
            DWZ.debug(url);
            if (!url.isFinishedTm()) {
                return false;
            }
            data._gridId = grid._gridId;
            if (grid.options.queryable) {
                $.extend(data, $.jGridTool.getQueryData(grid));
            }
            if ($.isFunction(grid.options.getQueryData)) {
                $.extend(data, grid.options.getQueryData());
            }
            if (grid.options.pageable) {
                $.extend(data, grid.page);
            }
            var ordersString = "";
            $.each(grid.orders, function (field, orderType) {
                ordersString += (field + ' ' + orderType + ',');
            });
            // 后台排序
            if (!ordersString) {
                ordersString = grid.defaultOrderString;
            } else {
                ordersString = ordersString.slice(0, -1);
            }
            $.extend(data, {
                ordersString: ordersString
            });

            // 保存grid的查询数据
            grid.options.postData = $.extend({}, data);
            DWZ.ajax({
                url: url,
                data: data,
                alert: false,
                success: function (rs) {
                    var json = new Object();
                    if ($.isPlainObject(rs.data)) {
                        json = rs.data;
                    } else {
                        json = rs;
                    }
                    //没有数据不加载
                    if (json.totalCount <= 0) {
                        var $tbody = grid.tbody, $tr = $('<tr/>');
                        $tr = $.jGridTool.$blankTr.clone(true);
                        $('>td>div', $tr).text($.validator.messages.noData || '======列表无数据=====');
                        $tbody.html($tr)
                        return;
                    }
                    if (grid.options.pageable && $.isPlainObject(json)) {
                        if (json.numPerPage > json.totalCount && json.pageNum > 1) {
                            grid.page.pageNum = 1;
                            grid.page.startRow = 1;
                            grid.page.endRow = json.numPerPage;
                            $.jGridTool.loadData(grid);
                            return;
                        }
                        $.jGridTool.setPagination(grid, {
                            numPerPage: json.numPerPage,
                            pageNum: json.pageNum,
                            totalCount: json.totalCount,
                            startRow: json.startRow,
                            endRow: json.endRow
                        });
                    }
                    if (json.data) {
                        $.jGridTool.fillGrid(grid, json.data);
                    } else {
                        $.jGridTool.fillGrid(grid, json);
                    }
                    if ($.isFunction(grid.options.loadcomplete)) {
                        grid.options.loadcomplete(json, grid);
                    }
                }
            });
        },
        // 数据填充
        fillGrid: function (grid, data) {
            var $tbody = grid.tbody, $table = $tbody.parent(), $tr = $('<tr/>');
            $tbody.fadeOut(0, function () {
                if (data.length === 0) {
                    $.jGridTool.clearData(grid);
                    return;
                }
                $tbody.empty().detach();
                // 追加数据
                $.each(data, function (index, object) {
                    $.jGridTool._addRowForObj(grid, index, object, $tbody);
                });
                $tbody.appendTo($table);
                var $ths = grid.thead.find(">tr:last-child>th"), $trs = $tbody.find(">tr:first>td");
                $.each($ths, function (index, th) {
                    $($trs[index]).css('width', th.style.width);
                });
                $tbody.fadeIn(100, function () {
                    if ($.isFunction(grid.options.fillcallback)) {
                        grid.options.fillcallback($tbody);
                    }
                });
            });
        },
        // 分页数据
        setPagination: function (grid, page) {
            grid.options.pagination = page;
            $('span[name="totalCount"]', grid.pagePanel).text(page.totalCount + pagePanelTotalItems);
            var totalPageNum = Math.ceil(page.totalCount / page.numPerPage);
            grid.pagination.data('totalPageNum', totalPageNum);
            $('>input:first', grid.jumpto).val(page.pageNum);
            if (page.pageNum < totalPageNum) {
                $.jGridTool.setPaginationAble(grid.nextPage, true);
                $.jGridTool.setPaginationAble(grid.lastPage, true);
            }
            if (page.pageNum > 1) {
                $.jGridTool.setPaginationAble(grid.firstPage, true);
                $.jGridTool.setPaginationAble(grid.prevPage, true);
            }
            if (page.pageNum === totalPageNum || totalPageNum === 0) {
                $.jGridTool.setPaginationAble(grid.nextPage, false);
                $.jGridTool.setPaginationAble(grid.lastPage, false);
            }
            if (page.pageNum === 1 || totalPageNum === 0) {
                $.jGridTool.setPaginationAble(grid.firstPage, false);
                $.jGridTool.setPaginationAble(grid.prevPage, false);
            }
            var firstNum = 1, lastNum = totalPageNum, pageNumShown = grid.options.page.pageNumShown;
            if (totalPageNum > pageNumShown) {
                if (totalPageNum - pageNumShown > page.pageNum) {
                    firstNum = page.pageNum;
                    lastNum = page.pageNum + pageNumShown - 1;
                } else {
                    lastNum = totalPageNum;
                    firstNum = totalPageNum - pageNumShown + 1;
                }
            }
            grid.prevPage.nextAll('.j-num').remove();
            for (var int = firstNum; int < (lastNum + 1); int++) {
                $('<li class="j-num"/>').addClass((int === page.pageNum) ? ' selected' : '').append($('<a href="javascript:;"/>').append(int).on('click', function () {
                    var num = parseInt($(this).text());
                    grid.page.pageNum = num;
                    grid.page.startRow = (num - 1) * grid.page.numPerPage + 1;
                    grid.page.endRow = num * grid.page.numPerPage;
                    $.jGridTool.loadData(grid);
                })).hoverClass('hover').insertBefore(grid.nextPage);
            }
        },
        // 分页导航设置
        setPaginationAble: function ($pb, able) {
            if (able) {
                $pb.removeClass('disabled');
                $pb.find('>a').show().css({
                    color: '#000 !important'
                });
                $pb.find('>span').hide();
            } else {
                $pb.addClass('disabled');
                $pb.find('>a').hide();
                $pb.find('>span').show();
            }
        },
        // 获取查询条件输入
        getQueryData: function (grid) {
            var queryData = {};
            $.each($('[name]', grid.queryPanel), function () {
                var $this = $(this);
                queryData[$this.attr('name')] = $this.val() || $this[0].value;
            });
            if (grid.advancedQueryPanel) {
                $.each($('[name]', grid.advancedQueryPanel), function () {
                    var $this = $(this);
                    queryData[$this.attr('name')] = $this.val() || $this[0].value;
                });
            }
            return queryData;
        },
        // 锁定列/固定列
        lockColumn: function (grid) {
            var hLeft = grid.thead.parents('.gridThead:first').cssv("left");
            for (var columnIndex = 0; columnIndex < grid.options.lockColumnNum; columnIndex++) {
                var $th = $('tr:first > th:eq(' + columnIndex + ')', grid.thead);
                $('>:nth-child(' + (columnIndex + 1) + ')', $('tr', grid.thead.parents('.grid:first'))).addClass('lockColumn').css({
                    width: $th[0].style.width,
                    left: -hLeft
                });
            }
        },
        // 数据空行
        $blankTr: $('<tr/>').append($('<td/>').addClass("noData").append('<div/>')).on('click', function () {
            return false;
        }),
        // 添加行
        appendRow: function (grid, data) {
            this._addRow(grid, undefined, data);
        },
        // 插入行
        insertRow: function (grid, rowIndex, data) {
            if (!isNaN(rowIndex)) {
                this._addRow(grid, rowIndex, data);
            } else {
                this._addRow(grid, undefined, data);
            }
            var $tbody = grid.tbody;
            if (rowIndex === 0) {
                var $ths = grid.thead.find(">tr:last-child>th"), $trs = $tbody.find(">tr:first>td");
                $.each($ths, function (index, th) {
                    $($trs[index]).css('width', th.style.width);
                });
            }
            var indexColumn = -1;
            $.each(grid.options.columns, function (index, field) {
                if (field.field === '_index') {
                    indexColumn = index + 1;
                    return false;
                }
            });
            if (indexColumn >= 0) {
                var _index = 1;
                $.each($('>td:nth-child(' + indexColumn + ')', $('>tr', $tbody)), function () {
                    var $this = $(this);
                    if ($('>div', $this).length) {
                        $('>div', $this).text(_index++);
                    } else {
                        $this.text(_index++);
                    }
                });
            }
        },
        _addRow: function (grid, index, data) {
            if (!data || $.isPlainObject(data)) {
                var $tbody = grid.tbody;
                if ($('>tr>.noData', $tbody).length === $('>tr', $tbody).length) {
                    $tbody.empty();
                }
                this._addRowForObj(grid, index, data, $tbody);
            }
            // 后期可能会有数组
        },
        _addRowForObj: function (grid, index, object, $tbody, parentId, pLeft) {
            if (index === undefined) {
                index = $('>tr', $tbody).length;
            }
            var $tr = $('<tr/>').data('__index__', index).data('__source__', object);
            if (object) {
                $tr.data(object);
            }
            $.each(grid.options.columns, function (columnIndex, field) {
                var textValue = '', td = $('<td/>');
                if ($.isPlainObject(field)) {
                    var columnField = field.field;
                    if (field.type === 'checkbox') {
                        var fieldSplit = field.fieldSplit || ';', text = '';
                        if (object) {
                            if (columnField.indexOf(fieldSplit) !== -1) {
                                var checkFields = columnField.split(fieldSplit);
                                $.each(checkFields, function () {
                                    text += object[this] + fieldSplit;
                                });
                                text = text.slice(0, -1);
                            } else {
                                text = object[columnField];
                            }
                        }
                        if (!grid.options._shiftbox) {
                            grid.options._shiftbox = field.group || '';
                        }
                        textValue = $('<input type="checkbox"/>').attr('name', field.group).val(text);
                    } else if (field.type === 'date') { // 对于Date类型的数据进行格式化
                        if (object && object[columnField]) {
                            var date = new Date(parseInt(object[columnField]));
                            textValue = date.formatDate(field.format ? field.format : "yyyy-MM-dd HH:mm:ss");
                        }
                    } else if (field.type === 'textInput') {
                        textValue = $('<input class="textInput" type="text"/>').val(object[columnField]).addClass(field.inputClass || '');
                    } else if (columnField === '_index') {
                        if (grid.page) {
                            textValue = index + grid.page.startRow;
                        } else {
                            textValue = index + 1;
                        }
                    } else if (columnField === '_lookup') {
                        var $btnSelect = $('<a/>').addClass('btnSelect bringBack').text('选择'), backData = {};
                        $.each(field.bringBackFields, function () {
                            backData[this] = object[this];
                        });
                        textValue = $btnSelect.on('click', function () {
                            $.bringBack(backData);
                        });
                    } else if ($.isFunction(field.transform)) {
                        textValue = field.transform(object[columnField]);
                    } else if (object) {
                        textValue = object[columnField];
                    }
                }
                if (grid.options.wrapTD || grid.options.lockColumnNum > columnIndex) {
                    if (typeof textValue === 'string') {
                        td.append($('<div/>').text(textValue));
                    } else {
                        td.append($('<div/>').append(textValue));
                    }
                } else {
                    if (typeof textValue === 'string') {
                        td.text(textValue);
                    } else {
                        td.append(textValue);
                    }
                }
                if ($.isFunction(field.tdrender)) {
                    field.tdrender.call(textValue, grid.options.wrapTD ? td.find('>div') : td, object, field.field);
                }
                $tr.append(td.attr({
                    columnField: field.field ? field.field : ''
                }));
            });
            var rowNums = $('>tr', $tbody).length;
            if (rowNums <= index || grid.options.treeTable) {
                $tbody.append($tr);
            } else {
                $tr.insertBefore($('>tr:eq(' + index + ')', $tbody));
            }
            if (rowNums === 0) {
                var $ths = grid.thead.find(">tr:last-child>th"), $trs = $tbody.find(">tr:first>td");
                $.each($ths, function (index, th) {
                    $($trs[index]).css('width', th.style.width);
                });
            }
            // 树列表
            if (grid.options.treeTable) {
                var treeChildren = grid.options.childrenField, cId = parentId ? (parentId + index) : ('p' + index),
                    modelClass = grid.options.treeModel || 'collapsed';

                $tr.attr({
                    'data-tr_parent_id': parentId || '',
                    'data-tr_id': cId
                }).addClass(modelClass);

                if (parentId && modelClass === 'collapsed') {
                    $tr.hide();
                }

                var $d = (grid.options.wrapTD || grid.options.lockColumnNum > 0) ? $('>td:first>div', $tr) : $('>td:first', $tr);
                if (treeChildren && object[treeChildren] && object[treeChildren].length) {
                    $d.prepend($('<span style="padding-left: ' + ((pLeft || 0) * 19) + 'px;" class="indenter"><a href="#">&nbsp;</a></span>').on('click', function () {
                        if ($('>tr[data-tr_parent_id^=' + $tr.attr('data-tr_id') + ']:animated', $tbody).length) {
                            return false;
                        }
                        if ($tr.is('.collapsed')) {
                            $tr.removeClass('collapsed').addClass('expanded');
                            $.jGridTool.treeExpand($tbody, $tr);
                        } else {
                            $('>tr[data-tr_parent_id^=' + $tr.attr('data-tr_id') + ']', $tbody).slideUp(200, function () {
                                $tr.removeClass('expanded').addClass('collapsed');
                            });
                        }
                        return false;
                    }));
                    $.each(object[treeChildren], function (i, obj) {
                        $.jGridTool._addRowForObj(grid, i, obj, $tbody, cId, (pLeft || 0) + 1);
                    });
                } else {
                    $d.prepend('<span style="padding-left: ' + ((pLeft || 0) * 19 + 19) + 'px;" />');
                }
            }
        },
        // 树表展开
        treeExpand: function ($tbody, $tr) {
            var trId = $tr.attr('data-tr_id');
            $('>tr[data-tr_parent_id=' + trId + ']', $tbody).each(function () {
                if ($tr.is('.expanded')) {
                    $(this).slideDown(200);
                    $.jGridTool.treeExpand($tbody, $(this));
                }
            });
        },
        // 列表样式刷新
        refresh: function (grid) {
            var $tbody = grid.tbody;
            if ($('>tr', $tbody).length === 0) {
                this.clearData(grid);
            } else {
                var $ths = $(">tr:last-child>th", grid.thead), $trs = $(">tr:first>td", $tbody);
                $.each($ths, function (index, th) {
                    $($trs[index]).css('width', th.style.width);
                });
            }
        },
        // 获取/设置属性
        option: function (grid, ops) {
            if (ops && $.isPlainObject(ops)) {
                var needRefactor = (ops.columns && ops.columns !== grid.options.columns) || (ops.lockColumnNum && ops.lockColumnNum !== grid.options.lockColumnNum);
                $.extend(grid.options, ops);
                if (needRefactor) {
                    $.jGridTool.clearData(grid);
                    $.jGridTool.fillGridHeader(grid);
                }
            }
        },
        // 清空列表
        clearData: function (grid) {
            var $tbody = grid.tbody, $table = $tbody.parent(), $tr = this.$blankTr.clone(true);
            $('>td>div', $tr).text($.validator.messages.noData || '======列表无数据=====');
            $tbody.empty().detach().append($tr).appendTo($table).fadeIn(300);
            $('[type=checkbox]', grid.thead).removeAttr('checked');
        },
        // 生成表头
        fillGridHeader: function (grid, columns) {
            if (columns) {
                $.extend(true, grid.options, {
                    columns: columns
                });
            }
            var $thead = grid.thead, $tbody = grid.tbody, $tr = $('<tr/>').appendTo($thead.css({
                    height: grid.options.gridHeaderHeight
                }).empty()), $grid = $thead.parents('.gridPart:first'), $this = $grid.parent(),
                $gridHeader = $('>.gridHeader', $grid), $gridBody = $('>.gridBody', $grid),
                $gridScrollerBar = $('>.gridScrollerBar', $grid), $resizeMarker = $('>.resizeMarker', $grid),
                $resizeProxy = $('>.resizeProxy', $grid),
                gridWith = grid.options.hasBorder ? $this.width() - 1 : $this.width();
            if (grid.options.width === 0 || grid.options.width === '100%' || grid.options.width < $this.width()) {
                grid.options.width = $this.width();
            }
            if (grid.options.fixedWidth) {
                grid.options.width = grid.options.fixedWidth;
            }
            var tableWith = grid.options.width - 20;
            $('table', $gridHeader).css({
                width: tableWith
            });
            $('table', $gridBody).css({
                width: tableWith
            });

            $.each(grid.options.columns, function (columnIndex, column) {
                var $th = $('<th/>').addClass(column.align || '').attr({
                    title: column.title || column.text || '',
                    orderfield: column.field
                }).css({
                    width: column.width - (100 * column.width / grid.options.width) - 2
                });
                $th.hoverClass("hover").append($('<div/>').addClass('gridCol').append(column.text || ''));
                if (column.type === 'checkbox') {
                    grid.options.checkGroup = column.group;
                    $th.find('.gridCol').append($('<input class="checkboxCtrl" type="checkbox" />').attr('group', column.group));
                }
                if ($.isFunction(column.thrender)) {
                    column.thrender($th.find('.gridCol'));
                }
                if (column.query && column.query === true) {
                    grid.options.query.queryfields.push(columnToQuery(column));
                }
                /*
                if (grid.options.query.queryfields.length) {
                    grid.options.query.queryfields.sort(function(a, b) {
                        if (a.index != undefined) {
                            if (a.index > (b.index || -1)) {
                                return 1;
                            }
                        }
                        return -1;
                    })
                }
                */
                var orderSub = '';
                if (column.orderTable) {
                    orderSub = column.orderTable + '.';
                }
                $th.on('click', '.gridCol', function () {
                    if (!column.orderable) {
                        column.orderable = grid.options.orderable;
                    }
                    var orderType = grid.options.ordertype, // 'multiple' ||
                        // 'single';
                        clearOrders = function () {
                            if (orderType === 'single') {
                                $('.asc, .desc', $tr).removeClass('asc desc');
                                grid.orders = {};
                            }
                        };
                    if (column.type !== 'checkbox' && column.field !== '_index' && column.field !== '_lookup' && column.orderable) {
                        if ($th.hasClass('asc')) {
                            clearOrders();
                            $th.removeClass('asc');
                            $th.addClass('desc');
                            delete grid.orders[orderSub + column.field];
                            grid.orders[orderSub + column.field] = "desc";
                        } else if ($th.hasClass('desc')) {
                            clearOrders();
                            $th.removeClass('desc');
                            delete grid.orders[orderSub + column.field];
                        } else {
                            clearOrders();
                            $th.addClass('asc');
                            delete grid.orders[orderSub + column.field];
                            grid.orders[orderSub + column.field] = "asc";
                        }
                        $.jGridTool.loadData(grid);
                    }
                });
                if (column.defaultOrder !== undefined) {
                    grid.defaultOrderString = orderSub + column.field + ' ' + column.defaultOrder;
                    if (column.orderIcon) {
                        $th.addClass(column.defaultOrder);
                    }
                }
                if (!grid.defaultOrderString && column.field.toLowerCase() === 'createdatetime') {
                    grid.defaultOrderString = orderSub + 'createDateTime desc';
                }
                if (grid.options.lockColumnNum > columnIndex) {
                    $th.addClass('lockColumn');
                }
                $th.appendTo($tr);
            });

            if (grid.options.lockColumnNum > 0) {
                $('table', $grid).addClass('lockColumnTable');
            } else {
                $('table', $grid).removeClass('lockColumnTable');
            }

            var _setScroll = function (gridWith) {
                var actualTableWidth = $(".gridThead > table", $gridHeader).width() || tableWith, hasScroller = false;
                if (actualTableWidth > gridWith) {
                    $('>div', $gridScrollerBar).width(actualTableWidth + 20);
                    $('>div', $gridScrollerBar).height(1).end().height(16);
                    hasScroller = true;
                } else {
                    $('>div', $gridScrollerBar).width(gridWith);
                    $('>div', $gridScrollerBar).height(0).end().height(0);
                }
                var gridLayoutH = $grid.attr('layoutH');
                if (grid.options.layoutH > 0) {
                    if (!gridLayoutH) {
                        $grid.attr('layoutH', grid.options.layoutH - grid.options.gridHeaderHeight);
                        $gridBody.attr('layoutH', grid.options.layoutH + (hasScroller ? 16 : 0));
                    } else {
                        $gridBody.attr('layoutH', parseInt(gridLayoutH) + grid.options.gridHeaderHeight + (hasScroller ? 16 : 0));
                    }
                } else if (grid.options.height) {
                    $grid.css({
                        height: grid.options.height + grid.options.gridHeaderHeight
                    });
                    $gridBody.css({
                        height: grid.options.height - (hasScroller ? 16 : 0)
                    });
                }
                // 使layoutH生效
                $(window).resize();
            };
            _setScroll(gridWith);
            if (!grid.options.columnresizeable) {
                return;
            }
            $(">tr", $thead).each(function () {
                $(">th", this).each(function (i) {
                    var th = this, $th = $(this);
                    $th.mouseover(function (event) {
                        var offset = $.jTableTool.getOffset(th, event).offsetX;
                        if ($th.outerWidth() - offset < 5) {
                            $th.css("cursor", "col-resize").mousedown(function (event) {
                                $resizeProxy.show().css({
                                    left: $.jTableTool.getRight(th) - ($th.is('.lockColumn') ? 0 : $gridScrollerBar.scrollLeft()),
                                    top: $.jTableTool.getTop(th),
                                    height: $grid.height() - ($gridScrollerBar.width() < $gridScrollerBar[0].scrollWidth ? 16 : 0),
                                    zIndex: 100,
                                    cursor: "col-resize"
                                });
                                $resizeMarker.show().css({
                                    left: $.jTableTool.getLeft(th) + 1 - ($th.is('.lockColumn') ? 0 : $gridScrollerBar.scrollLeft()),
                                    top: $.jTableTool.getTop(th),
                                    height: $grid.height() - ($gridScrollerBar.width() < $gridScrollerBar[0].scrollWidth ? 16 : 0),
                                    zIndex: 100
                                });
                                $resizeProxy.jDrag($.extend({}, {
                                    scop: true,
                                    cellMinW: 20,
                                    relObj: $resizeMarker[0],
                                    move: "horizontal",
                                    event: event,
                                    stop: function () {
                                        var pleft = $resizeProxy.position().left;
                                        var mleft = $resizeMarker.position().left;
                                        var move = pleft - mleft - $th.outerWidth() - 9;

                                        var cols = $.jTableTool.getColspan($th);
                                        var cellNum = $.jTableTool.getCellNum($th);
                                        var oldW = $th.width(), newW = $th.width() + move;

                                        $th.width(newW + "px");
                                        $(">td:nth-child(" + cellNum + ")", $('tr', $tbody)).width(newW + "px");
                                        var newTableWidth = $thead.parent().width() - oldW + newW;
                                        $thead.parent().css({
                                            width: newTableWidth
                                        });
                                        $tbody.parent().css({
                                            width: newTableWidth
                                        });
                                        _setScroll();
                                        $(".resizeMarker,.resizeProxy", $grid).hide();
                                    }
                                }));
                            });
                        } else {
                            $th.css("cursor", $th.attr("orderField") ? "pointer" : "default");
                            $th.unbind("mousedown");
                        }
                        return false;
                    });
                });
            });
        }
    };

    // 针对不支持 Array.indexOf
    var checkIndexOf = function (items, item) {
        var _index = -1;
        $.each(items, function (index, value) {
            if (value === item) {
                _index = index;
                return false;
            }
        });
        return _index;
    };
    // 如果使用layoutH布局时，其父元素有绝对布局且设置class为layoutPanel时，改变窗口大小时需要改变自身的高度
    $(win).on('resize', function () {
        $.each($('.layoutPanel'), function () {
            var $layoutPanel = $(this);
            $.each($('[layoutH]', $layoutPanel), function () {
                var $this = $(this);
                $this.css({
                    height: $layoutPanel.height() - parseInt($this.attr('layoutH'))
                });
            });
        });
    });
})(jQuery, window, DWZ, alertMsg, navTab);